import { GpEcsWorld } from "../GpEcsWorld";
import { Comp } from "../CompDef";
import { Sglt } from "../SgltDefine";
import { MathUtils, Vect3 } from "../../../common/MathUtils";
import { CommonSystem } from "./CommonSystem";
import ecs, { EcsComponent, EcsEntity, EcsEntityGroup} from "ecs-ts";
import { Vec3 } from "cc";
export class MoveSystem extends ecs.EcsSystem<GpEcsWorld> {
    tempVec3 = new Vect3()
    uiInfo: Sglt.UiInfo
    worldInfo: Sglt.WorldInfo

    constructor(world: GpEcsWorld, defaltGroupComps: (new () => EcsComponent)[] = [Comp.Transform, Comp.Move]) {
        super(world, defaltGroupComps);
        this.uiInfo = this.world.getSingleton(Sglt.UiInfo)
        this.worldInfo = this.world.getSingleton(Sglt.WorldInfo)

    }

    updateOrientation(transform: Comp.Transform, move: Comp.Move) {
        if (transform.__ownerId == 10000) {
            let a = 11
        }
        /**当前方向角度 */
        const orientationAngle = Comp.Transform.angle(transform)
        /**目标方向角度 */
        let targetAngle = orientationAngle
        /**目标方向 */
        let targetDirection: Vect3 = null
        if (transform.velocity.x != 0 || transform.velocity.y != 0) {//有动量朝向动量方向(说明遥杆在动)
            targetAngle = Math.atan2(transform.velocity.y, transform.velocity.x) + Math.PI
            targetDirection = transform.velocity
        } else if (move.targetPos.x != 0 || move.targetPos.y != 0) {//有目标位置朝向目标位置
            targetDirection = Vect3.subtract(this.tempVec3, move.targetPos, transform.pos)
            targetAngle = Math.atan2(targetDirection.y, targetDirection.x) + Math.PI
        }

        /**转身速度 */
        const rotateSpeed = transform.rotateSpeed

        /**转身方向 */
        let angularDirection = 0

        if (orientationAngle != targetAngle) {
            const isRight = MathUtils.isRight(targetDirection, transform.orientation)
            angularDirection = isRight ? 1 : -1
        }
        // if (orientationAngle != targetAngle) {
        //     angularDirection = MathUtils.radianToAngleIn360(orientationAngle) - MathUtils.radianToAngleIn360(targetAngle)>180 ? 1 : -1
        // }

        if (angularDirection != 0) {
            if (true || (targetDirection.x != 0 || targetDirection.y != 0) && Math.abs(orientationAngle - targetAngle) < 0.05) {
                transform.orientation.x = targetDirection.x
                transform.orientation.y = targetDirection.y

                Vect3.normalize(transform.orientation, transform.orientation)
            } else {
                Vect3.rotateZ(transform.orientation, transform.orientation, Vec3.ZERO, angularDirection * rotateSpeed)
            }
        }
    }

    updatePrefVelocity(entity: EcsEntity, transform: Comp.Transform, move: Comp.Move) {


        //#region 根据目标方向设置期望动力
        const moveMag = Vect3.mag(move.targetDirection)
        if (moveMag > 0) {
            Vect3.normalize(this.tempVec3, move.targetDirection)
            Vect3.set(transform.prefVelocity, Vect3.multiplyScalar(this.tempVec3, this.tempVec3, transform.moveSpeed * moveMag))
        } else if (move.hasMoveTargetPos || move.hasForceMoveTargetPos) {
            //如果有目标位置或者有强制移动目标位置（比目标位置优先级高）
            const direction = Vect3.subtract(this.tempVec3, move.targetPos, transform.pos)
            Vect3.normalize(this.tempVec3, direction)

            Vect3.set(transform.prefVelocity, Vect3.multiplyScalar(this.tempVec3, this.tempVec3, transform.moveSpeed))
            const distance = Vect3.distance(transform.pos, move.targetPos)
            if (distance < transform.moveSpeed || (this.world.elapsedTimeMs - move.lastFindPathTime) > 1000) {
                move.hasMoveTargetPos = false
            }


        } else {
            Vect3.set(transform.prefVelocity, Vect3.ZERO)
        }
        //#endregion


    }

    chechForceMove(entity: EcsEntity, transform: Comp.Transform, move: Comp.Move) {
        if (move.hasForceMoveTargetPos) {
            const distance = Vect3.distance(transform.pos, move.forceMoveTargetPos)
            if (distance > transform.moveSpeed / this.world.frameRate) {
                if (this.tryMoveTo(entity, transform, move, move.forceMoveTargetPos)) {
                    move.hasMoveTargetPos = true
                    // Vec3.set(move.targetPos, move.forceMoveTargetPos)
                    // entity.component(Comp.RVOMove).maxSpeed = transform.moveSpeed
                }

            } else {
                move.hasForceMoveTargetPos = false
            }


        }

    }

    /**尝试向一个目标移动 */
    tryMoveTo(entity: EcsEntity, transform: Comp.Transform, move: Comp.Move, targetPos: Vect3) {
        // const findTargetPos = this.world.system(CommonSystem).getNearestWalkablePos(transform, targetPos)
        // const startPos = this.world.system(CommonSystem).getNearestWalkablePos(transform, transform.pos)

        // let path: number[][] = []
        // if (findTargetPos && startPos) {
        //     path = this.world.system(CommonSystem).findPath(entity, startPos, findTargetPos, transform.radius)
        //     move.lastFindPathTime = this.world.elapsedTimeMs
        // }


        // let targetPathPoint
        // if (path.length == 1) {
        //     targetPathPoint = path[0]
        // } else if (path.length > 1) {
        //     path.shift()
        //     targetPathPoint = path.find(i => {
        //         const worldPos = this.worldInfo.gridPosToWorldPos(i[0], i[1])
        //         return Vec3.distance(worldPos, transform.pos) > transform.radius
        //     })
        // }

        // if (targetPathPoint) {
        //     const targetPos = this.worldInfo.gridPosToWorldPos(targetPathPoint[0], targetPathPoint[1])
        //     move.hasMoveTargetPos = true
        //     Vec3.set(move.targetPos, targetPos)
        // } else {
        //     move.hasMoveTargetPos = true
        //     Vec3.set(move.targetPos, targetPos)
        // }
        // return targetPathPoint

        let targetPathPoint = new Vect3(targetPos.x, targetPos.y, targetPos.z)
        if (targetPathPoint) {
            move.hasMoveTargetPos = true
            Vect3.set(move.targetPos, targetPathPoint)
        } else {
            move.hasMoveTargetPos = true
            Vect3.set(move.targetPos, targetPathPoint)
        }
        return targetPathPoint
    }

    update(): void {
        this.defaultGroup.forEach((entity) => {
            const transform = entity.component(Comp.Transform)
            const move = entity.component(Comp.Move)

            this.updateOrientation(transform, move)
            this.chechForceMove(entity, transform, move)
            this.updatePrefVelocity(entity, transform, move)

            Vect3.set(transform.velocity, transform.prefVelocity)
            Vect3.add(transform.pos, transform.pos, transform.velocity)


            // if ((transform.pos.x + transform.velocity.x < this.worldInfo.width / 2 && transform.pos.x + transform.velocity.x > this.worldInfo.width / -2 && transform.pos.y + transform.velocity.y < 0 && transform.pos.y + transform.velocity.y > this.worldInfo.height / -2)) {
            //     Vect3.add(transform.pos, transform.pos, transform.velocity)
            // }
            // Vect3.add(transform.pos, transform.pos, Vec3.set(this.tempVec3,0,2,0))

            // Vect3.set(transform.pos, transform.pos.x, entity.id%2==0?450:-200,transform.pos.z)
            // if (transform.angular != 0) {
            //     Vec3.rotateZ(transform.orientation, transform.orientation, cc.Vec3.ZERO, transform.angular)
            // }

            // transform.orientation.rotate(0.1)
        })

    }
}